/**
 * @Description:
 * @Author 卞鹏飞 <228443632@qq.com>
 * @create 23/11/24 PM2:00
 */

import { shallowRef, ref } from 'vue'
import Postmate from 'postmate'
import { hasOwn, isFunction, isObject } from 'sf-utils2'
import type { TChildOptions, TParentHandshake } from './postmate-types.ts'
// import { onMountedOrActivated } from '@shared/hooks/on-mounted-or-activated'

Postmate.debug = process.env.NODE_ENV !== 'production'

/**
 * 获取子窗口hooks
 * @example
 * @param options
 */
export function usePostmateChild(options: TChildOptions = {}) {
  const parentHandshake = shallowRef<TParentHandshake>()

  const msgId = ref()

  const handshake = shallowRef()

  options.model ||= {}

  const defaultModel = {
    // msgId: undefined,
    origin: window.location.origin,
    height: () => document.documentElement.offsetHeight || document.body.offsetHeight
  }

  Object.keys(defaultModel).forEach((key) => {
    if (!hasOwn(options.model, key)) {
      options.model[key] = defaultModel[key]
    }
  })

  handshake.value = new Postmate.Model(options.model)

  handshake.value.then((parent) => {
    parentHandshake.value = parent as TParentHandshake

    msgId.value = parentHandshake.value.msgId = options.model?.msgId

    const emit = parentHandshake.value.emit

    parentHandshake.value.emit = function () {
      const args = [...arguments]
      if (args[1]) {
        if (isObject(args[1])) {
          // const originData = args[1]
          // const data = {} as Record<string, any>
          args[1] = JSON.stringify({
            msgId: parentHandshake.value.msgId,
            data: args[1]
          })
        } else {
          args[1] = JSON.stringify({
            msgId: parentHandshake.value.msgId,
            data: args[1]
          })
        }
      }

      args[1] ||= JSON.stringify({
        msgId: parentHandshake.value.msgId,
        data: {}
      })

      return emit.call(this, ...args)
    }
  })

  /**
   * 注册模型
   * @param key
   * @param callback
   */
  const registerModel = (key: string, callback: (...args: any[]) => void) => {
    if (!isFunction(callback)) return console.error('注册callback参数必须是Function类型')
    options.model[key] = callback
  }

  return {
    // on,
    handshake,
    /**
     * 父窗口实例
     */
    parentHandshake,

    /**
     * 注册模型
     */
    registerModel,

    /**
     * 微应用id
     */
    msgId
  }
}
